/**
    Copyright (c) 2009 yakiimo02
    Distributed under the New BSD License.
    See included license.txt or http://www.yakiimo3d.com/NewBSDLicense.txt
**/

#include "DXUT.h"
#include "BitonicSortCPU.h"
#include "DXHelper.h"

BitonicSortCPU::BitonicSortCPU() : m_pBuffer( NULL ), m_pSRV( NULL )
{
}

BitonicSortCPU::~BitonicSortCPU()
{
}

/**
    @param pd3dDevice    [in]            D3D Device
    @param data            [in]            data to be sorted
*/
HRESULT BitonicSortCPU::Create( ID3D11Device* pd3dDevice, const BufTypeVector& data )
{
    HRESULT hr = S_OK;

    m_data = data;

    // create structured buffer for the cpu
    V_RETURN( CreateStructuredBufferForCPU( pd3dDevice, sizeof(BufType), static_cast< UINT >( m_data.size() ), &m_data[ 0 ], &m_pBuffer ) );

    // create shader resource view
    V_RETURN( CreateBufferSRV( pd3dDevice, m_pBuffer, &m_pSRV ) );
    
    return hr;
}

/**
    @param pd3dDevice                [in]            D3D Device
    @param pd3dImmediateContext        [in]            D3D Device Immediate Context
*/
void BitonicSortCPU::UpdateBuffer( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext )
{
    // I think there might be a faster, better way to copy the data for this case, but this gets the job done for now.
    D3D11_MAPPED_SUBRESOURCE MappedResource;
    pd3dImmediateContext->Map( m_pBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource );
    memcpy( MappedResource.pData, &m_data[ 0 ], m_data.size()*sizeof(BufType) );
    pd3dImmediateContext->Unmap( m_pBuffer, 0 );
}

/**
*/
void BitonicSortCPU::Destroy()
{
    SAFE_RELEASE( m_pBuffer );
    SAFE_RELEASE( m_pSRV );
}

/**
*/
void BitonicSortCPU::Update() 
{
    // do nothing
}

/**
    Sort data all at once in one frame.
*/
void BitonicSortCPU::UpdateOnce()
{
    if( m_bSortUp ) {
        SortUp();
    }
    else {
        SortDown();
    }
}